package com.rightsidetech.system.listener;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.rightsidetech.commom.utils.StringUtil;
import com.rightsidetech.system.dtos.dto.LogInfoDTO;
import com.rightsidetech.system.entity.SysAgentOperatorLog;
import com.rightsidetech.system.entity.SysOperatorLog;
import com.rightsidetech.system.entity.SysOperatorLogTemp;
import com.rightsidetech.system.mapper.SysAgentOperatorLogMapper;
import com.rightsidetech.system.mapper.SysOperatorLogMapper;
import com.rightsidetech.system.mapper.SysOperatorLogTempMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author: yhr
 * @Date: 2021-11-12 16:57
 */
@Slf4j
public class ReceiverRedisMessage {
    @Resource
    private SysOperatorLogMapper sysOperatorLogMapper;
    @Resource
    private SysAgentOperatorLogMapper sysAgentOperatorLogMapper;
    @Resource
    private SysOperatorLogTempMapper sysOperatorLogTempMapper;
    /**
     * 日志队列消息接收方法
     *
     * @param jsonMsg
     */
    public void logReceive(String jsonMsg) {
        LogInfoDTO logInfo = JSON.parseObject(jsonMsg, LogInfoDTO.class);
        List<SysOperatorLogTemp> logTemp = sysOperatorLogTempMapper.selectByUri(logInfo.getUri());
        List<String> contents = new ArrayList<>();
        Map<String, Object> oldObject = (Map<String, Object>) objectToMap(logInfo.getOldParam());
        Map<String, Object> newObject = (Map<String, Object>) objectToMap(logInfo.getNewParam());
        if (ObjectUtils.isEmpty(logTemp)){
            return;
        }
        logTemp.forEach(temp->{
            boolean flag = true;
            if (!StringUtils.isEmpty(temp.getNeedCompareField())) {
                String compareField = temp.getNeedCompareField();
                if (StringUtil.notNullAndWhitSpace(compareField)) {
                    //新老数据比较
                    String oldVal = oldObject.get(compareField) == null ? "" : oldObject.get(compareField).toString();
                    String newVal = newObject.get(compareField) == null ? "" : newObject.get(compareField).toString();
                    if (oldVal.equals(newVal)) {
                        flag = false;
                    }
                }
            }

            if (flag) {
                String modifyField = temp.getModifyField();
                String[] modifyTempFields = null;
                if (StringUtil.notNullAndWhitSpace(modifyField)) {
                    modifyTempFields = modifyField.split("-");
                }
                //进行字段替换
                if (null == modifyTempFields || modifyTempFields.length == 0) {
                    contents.add(temp.getModifyTemp());
                } else {
                    boolean isKy = false;
                    isKy = StringUtils.isEmpty(temp.getKeyValue()) ? false:true;
                    String content = temp.getModifyTemp();
                    for (String fieldName : modifyTempFields) {
                        if (content.contains("old_" + fieldName)) {
                            String oldVal = oldObject.get(fieldName) == null ? "" : oldObject.get(fieldName).toString();
                            if (isKy) {
                                Map<String, String> keyValue = JSON.parseObject(temp.getKeyValue(), Map.class);
                                oldVal = StringUtils.isEmpty(keyValue.get(oldVal)) ? oldVal:keyValue.get(oldVal);
                            }
                            content = content.replace("old_" + fieldName, oldVal);
                        }
                        if (content.contains("new_" + fieldName)) {
                            String newVal = newObject.get(fieldName) == null ? "" : newObject.get(fieldName).toString();
                            if (isKy) {
                                Map<String, String> keyValue = JSON.parseObject(temp.getKeyValue(), Map.class);
                                newVal = StringUtils.isEmpty(keyValue.get(newVal)) ? newVal:keyValue.get(newVal);
                            }
                            content = content.replace("new_" + fieldName, newVal);
                        }
                    }
                    contents.add(content);
                }
            }
        });
        if (contents.isEmpty()) {
            return;
        }
        if (StringUtils.isEmpty(logInfo.getAgentId())){
            List<SysOperatorLog> list = new ArrayList<>();
            contents.forEach(content -> {
                SysOperatorLog sysOperatorLog = new SysOperatorLog();
                sysOperatorLog.setLoginInfoId(logInfo.getAccountId());
                sysOperatorLog.setLoginName(logInfo.getLoginName());
                sysOperatorLog.setMethodName(logTemp.get(0).getMethodName());
                sysOperatorLog.setUrl(logInfo.getUri());
                sysOperatorLog.setDetails(content);
                sysOperatorLog.setCreatedAt(new Date());
                Object param = logInfo.getParam();
                if (null != param && JSON.toJSONString(param).length() <= 500) {
                    sysOperatorLog.setRequestParam(JSON.toJSONString(param));
                }
                list.add(sysOperatorLog);
            });
            sysOperatorLogMapper.saveList(list);
        }else {
            List<SysAgentOperatorLog> list = new ArrayList<>();
            contents.forEach(content->{
                SysAgentOperatorLog sysAgentOperatorLog = new SysAgentOperatorLog();
                sysAgentOperatorLog.setLoginInfoId(logInfo.getAccountId());
                sysAgentOperatorLog.setAgentInfoId(logInfo.getAgentId());
                sysAgentOperatorLog.setLoginName(logInfo.getLoginName());
                sysAgentOperatorLog.setMethodName(logTemp.get(0).getMethodName());
                sysAgentOperatorLog.setUrl(logInfo.getUri());
                sysAgentOperatorLog.setDetails(content);
                sysAgentOperatorLog.setCreatedAt(new Date());
                Object param = logInfo.getParam();
                if (null != param && JSON.toJSONString(param).length() <= 500) {
                    sysAgentOperatorLog.setRequestParam(JSON.toJSONString(param));
                }
                list.add(sysAgentOperatorLog);
            });
            sysAgentOperatorLogMapper.saveList(list);
        }
    }

    private Map<?, ?> objectToMap(Object obj) {
        if (obj == null) {
            return null;
        }
        ObjectMapper mapper = new ObjectMapper();
        mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        Map<?, ?> mappedObject = mapper.convertValue(obj, Map.class);
        return mappedObject;
    }
}
